#pragma once
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using namespace std;
uint16_t defaultport = 8080;
string defaultip = "0.0.0.0";
class udpserver
{
public:
    udpserver(const uint16_t &port = defaultport, const string &ip = defaultip)
        : sockfd_(0), ip_(ip), port_(port)
    {
    }
    void Init()
    {
        // 1.创建套接字
        sockfd_ = socket(AF_INET, SOCK_DGRAM, 0);
        if (sockfd_ < 0)
        {
            cout << "创建套接字失败" << endl;
            exit(22);
        }
        cout << "创建套接字成功" << endl;
        // 2.绑定套接字
        struct sockaddr_in local;
        bzero(&local, sizeof(local));
        local.sin_family = AF_INET;
        local.sin_port = htons(port_);
        local.sin_addr.s_addr = INADDR_ANY;
        if (bind(sockfd_, (struct sockaddr *)&local, sizeof(local)) < 0)
        {
            cout << "绑定端口失败,直接退出" << endl;
            exit(8);
        }
        cout << "绑定套接字成功" << endl;
    }
    void Run()
    {
        char *buffer[1024];
        while (true)
        {
            struct sockaddr_in client; // 存储客户端的结构体
            socklen_t len = sizeof(client);
            ssize_t n = recvfrom(sockfd_, buffer, sizeof(buffer) - 1, 0,
                                 (struct sockaddr *)&client, &len);
            if (n < 0)
            {
                cout << "接收客户端信息失败，现象：字节数小于0" << endl;
                continue;
            }
            // 充当一次数据处理
            cout << "打印客户端传过来的数据" << buffer << endl;
            buffer[n] = 0;
            sendto(sockfd_, buffer, sizeof(buffer), 0, (struct sockaddr *)&client, len);
            cout << "数据返回给客户端完成" << endl;
        }
    }

private:
    int sockfd_;
    string ip_;
    uint16_t port_;
};